package chaoyue.study.exception;

/**
 * finally使用注意事项
 * 1.finally中进行的变量赋值无法改变返回值的内容
 * 2.finally中进行return会覆盖掉原有try语句中的return
 * 3.finally中抛出异常会吞掉原有try语句中的异常
 */
public class FinallyTest {
    public static void main(String[] args) {
        // 测试在finally中对返回值变量进行重新赋值
        System.out.println("test1: " + test1()); // 0
        // 测试在finally中直接进行return
        System.out.println("test2: " + test2()); // 2
        // 测试在finally中抛出异常
        System.out.println("test2: " + test3()); // RuntimeException
    }

    /**
     * finally无法改变返回值的内容
     * 虽然return语句在finally语句之后执行，但是finally并不能改变返回值的内容
     * 返回值会被临时保存在一个临时变量中，等finally语句执行结束后再返回临时变量中的内容
     * 这么做是为了保证语义的正确性
     */
    public static int test1() {
        int ret = 0;
        try {
            return ret;
        } finally {
            ret = 2;// finally中将ret变量的值改为2 但是实际最后返回的值还是0
        }
    }

    /**
     * finally会覆盖原有return
     * finally中如果有return，则会把原来的return覆盖掉
     * 因为finally语句会在try中的return语句之前执行
     */
    public static int test2() {
        int ret = 0;
        try {
            return ret;
        } finally {
            return 2;
        }
    }


    /**
     * finally会隐藏原有异常堆栈
     * 抛出的点作为异常的新起点
     */
    public static int test3() {
        int ret = 0;
        try {
            int a = 5 / 0;
            return ret;
        } finally {
            throw new RuntimeException("chaoyue");
        }
    }
}
